package platform.cas.server.authentication.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;

/**
 * <font color="#AA2222"><b>MD5算法密码加密实现</b></font><br />
 * 
 * @Company 中国协同教学（集团）有限公司
 * @author Jacken(陈文光<chenjacken@gmail.com>)
 * @version 1.0 2010-11-24
 * @CreateDate 2010-11-24
 * 
 */
public class Md5PwdEncoder implements PwdEncoder {
	/**
	 * 默认盐salt值
	 */
	private String salt = "GZXTJY";
	/**
	 * 带盐MD5加密是否严密,默认false
	 */
	private boolean strict = false;

	public String encodePassword(String rawPass) {
		String saltedPass = mergePasswordAndSalt(rawPass, salt);
		MessageDigest messageDigest = getMessageDigest();
		byte[] digest;
		try {
			digest = messageDigest.digest(saltedPass.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			throw new IllegalStateException("UTF-8 not supported!");
		}
		return new String(Hex.encodeHex(digest));
	}

	public boolean isPasswordValid(String encPass, String rawPass) {
		String pass1 = "" + encPass;
		String pass2 = encodePassword(rawPass);
		return pass1.equals(pass2);
	}

	/**
	 * 算法,例如 DSA, RSA, MD5 or SHA-1;已经设置为MD5
	 * 
	 * @return
	 */
	protected final MessageDigest getMessageDigest() {
		String algorithm = "MD5";
		try {
			return MessageDigest.getInstance(algorithm);
		} catch (NoSuchAlgorithmException e) {
			throw new IllegalArgumentException("No such algorithm ["
					+ algorithm + "]");
		}
	}

	/**
	 * 合并密码password和盐salt,严密时盐salt字符串不能存在<code>"{"</code>或<code>"}"</code>
	 * 
	 * @param password
	 *            密码
	 * @param salt
	 *            盐
	 * @return 返回合并字符串:password{salt}
	 */
	protected String mergePasswordAndSalt(String password, Object salt) {
		if (password == null) {
			password = "";
		}
		if (strict && (salt != null)) {
			if ((salt.toString().lastIndexOf("{") != -1)
					|| (salt.toString().lastIndexOf("}") != -1)) {
				throw new IllegalArgumentException(
						"Cannot use { or } in salt.toString()");
			}
		}
		if ((salt == null) || "".equals(salt)) {
			return password;
		} else {
			return password + "{" + salt.toString() + "}";
		}
	}

	/**
	 * 获取带盐MD5加密是否严密,ture为严密加密
	 * 
	 * @return
	 */
	public boolean getStrict() {
		return strict;
	}

	/**
	 * 设置带盐MD5加密是否严密,ture为严密加密
	 * 
	 * @return
	 */
	public void setStrict(boolean strict) {
		this.strict = strict;
	}

	/**
	 * 获得盐值salt
	 * 
	 * @return 盐值salt
	 */
	public String getSalt() {
		return salt;
	}

	/**
	 * 设置盐salt值,一般为用户名
	 * 
	 * @return void
	 */
	public void setSalt(String salt) {
		this.salt = salt;
	}

}
